package me.szlx.thing.parser;

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import me.szlx.thing.Thing;
import me.szlx.thing.ThingException;
import me.szlx.thing.Trait;
import me.szlx.thing.Traits;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Collectors;

public class TypesafeConfigParser<T extends Thing> extends AbstractThingParser<T> implements ThingParser<T> {
    private static final String ID = "id";
    private static final String NAME = "name";
    private static final String DESCRIPTION = "description";
    private static final String TRAITS = "traits";
    private static final String VALUE = "value";

    @Override
    protected List<T> doParse(InputStream resource) {
        Config config = ConfigFactory.parseReader(new InputStreamReader(resource));
        String prefix = getPrefix();
        if (prefix == null) {
            throw new ThingException("必须指定资源的键");
        }
        if (prefix.endsWith(".")) {
            prefix = prefix.substring(0, prefix.length() - 1);
        }
        return config.getConfigList(prefix).stream().map(thingCfg -> {
            String code = thingCfg.getString(ID);
            String name = thingCfg.getString(NAME);
            String description = thingCfg.hasPath(DESCRIPTION) ? thingCfg.getString(DESCRIPTION) : null;
            Traits traits = null;
            if (thingCfg.hasPath(TRAITS)) {
                List<Trait> traitList =
                        thingCfg.getConfigList(TRAITS).stream().map(traitCfg -> {
                            String traitName = traitCfg.getString(NAME);
                            String traitValue = traitCfg.hasPath(VALUE) ? traitCfg.getString(VALUE) : null;
                            return createTrait(traitName, traitValue);
                        }).collect(Collectors.toList());
                traits = Traits.of(traitList);
            }
            return createThing(code, name, description, traits);
        }).collect(Collectors.toList());
    }
}
